package cn.wolfcode.wolf2w.redis.service.impl;

import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.redis.service.IStrategyRedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.DateUtil;
import cn.wolfcode.wolf2w.redis.vo.StrategyStatisVo;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyRedisServiceImpl implements IStrategyRedisService {
	@Autowired
	private StringRedisTemplate template;
	@Autowired
	private IStrategyService strategyService;

	//阅读数
	@Override
	public void viewnumIncreas(String sid) {
		// 从redis中获取vo
		StrategyStatisVo strategyStatisVo = this.getStrategyStatisVo(sid);
		// 阅读数+1
		strategyStatisVo.setViewnum(strategyStatisVo.getViewnum() + 1);
		// 设置到redis中
		this.setStrategyStatisVo(strategyStatisVo);
	}

	// 评论数
	@Override
	public void replynumIncreas(String sid) {
		// 从redis中获取vo
		StrategyStatisVo strategyStatisVo = this.getStrategyStatisVo(sid);
		// 评论数+1
		strategyStatisVo.setReplynum(strategyStatisVo.getReplynum() + 1);
		// 设置到redis中
		this.setStrategyStatisVo(strategyStatisVo);
	}

	// 点击收藏/取消收藏
	@Override
	public boolean favornumIncreas(String sid, String uid) {
		String favorKey = RedisKeys.VERIFY_USER_STRATEGY_FAVOR.join(uid);
		StrategyStatisVo strategyStatisVo = this.getStrategyStatisVo(sid);

		// redis中是否存在该key
		// 获取当前用户的收藏列表
		List<String> sidList = this.getUserFavorList(uid);

		// 用户是否收藏该攻略
		if (sidList.contains(sid)) {
			// 取消收藏,并且数量-1
			sidList.remove(sid);
			strategyStatisVo.setFavornum(strategyStatisVo.getFavornum() - 1);
		} else {
			// 收藏,并且数量+1
			sidList.add(sid);
			strategyStatisVo.setFavornum(strategyStatisVo.getFavornum() + 1);
		}
		// 把收藏的列表覆盖
		template.opsForValue().set(favorKey, JSON.toJSONString(sidList));
		// 覆盖vo
		this.setStrategyStatisVo(strategyStatisVo);
		return sidList.contains(sid);
	}

	// 获取用户的收藏列表
	public List<String> getUserFavorList(String userId) {
		String favorKey = RedisKeys.VERIFY_USER_STRATEGY_FAVOR.join(userId);
		if (template.hasKey(favorKey)) {
			String sidListString = template.opsForValue().get(favorKey);
			List<String> sidList = JSON.parseArray(sidListString, String.class);
			return sidList;
		}
		return new ArrayList<>();
	}

	//  获取所有用户的收藏列表
	public List<List<String>> getAllFavorList() {
		String favorKey = RedisKeys.VERIFY_USER_STRATEGY_FAVOR.join("*");
		Set<String> favorKeys = template.keys(favorKey);
		List<List<String>> allSidList = new ArrayList<>();
		for (String key : favorKeys) {
			String sidListString = template.opsForValue().get(key);
			// 切割, 获取userId
			String[] split = key.split(":");
			String userId = split[split.length - 1];
			// 把收藏列表转换成Java对象
			List<String> sidList = JSON.parseArray(sidListString, String.class);
			// 把userId设置在第一位,一并传过去
			sidList.add(0,userId);
			allSidList.add(sidList);
		}
		return allSidList;
	}

	// 点赞
	@Override
	public boolean strategyThumbup(String sid, String uid) {
		String thumbupKey = RedisKeys.VERIFY_STRATEGY_THUMBUP.join(sid, uid);
		// 存在就不能再顶
		if (template.hasKey(thumbupKey)) {
			return false;
		}
		// 不存在,就顶他,并且设置一个有效时间(当天23:59:59-当前时间)
		template.opsForValue().set(thumbupKey, "", DateUtil.getDateBetween(DateUtil.getEndDate(new Date()), new Date()), TimeUnit.SECONDS);
		// 获取vo
		StrategyStatisVo strategyStatisVo = this.getStrategyStatisVo(sid);
		// 点赞数+1
		strategyStatisVo.setThumbsupnum(strategyStatisVo.getThumbsupnum() + 1);
		// 设置vo
		this.setStrategyStatisVo(strategyStatisVo);
		return true;
	}

	// 查询所有的key
	@Override
	public List<StrategyStatisVo> queryStrategyVoByPattern(String pattern) {
		// verify_strategy_vo*
		String keyPattern = RedisKeys.VERIFY_STRATEGY_VO.join(pattern);
		Set<String> keys = template.keys(keyPattern);
		List<StrategyStatisVo> vos = new ArrayList<>();

		//遍历vo的key集合, 获取 vo字符串
		for (String key : keys) {
			String voString = template.opsForValue().get(key);
			// 转换成java类型的vo
			StrategyStatisVo vo = JSON.parseObject(voString, StrategyStatisVo.class);
			// 把vo添加到vos集合中
			vos.add(vo);
		}

		return vos;
	}

	// 获取vo
	@Override
	public StrategyStatisVo getStrategyStatisVo(String sid) {
		String key = RedisKeys.VERIFY_STRATEGY_VO.join(sid);
		StrategyStatisVo strategyStatisVo;
		// 第一次查看时,初始化
		if (!template.hasKey(key)) {
			strategyStatisVo = new StrategyStatisVo();
			strategyStatisVo.setStrategyId(sid);
			Strategy strategy = strategyService.get(sid);
			//将指定攻略的统计数据量拷贝到vo对象中
			BeanUtils.copyProperties(strategy, strategyStatisVo);
			template.opsForValue().set(key, JSON.toJSONString(strategyStatisVo));
		} else {
			String stringVo = template.opsForValue().get(key);
			// 把json格式的字符串转换成java对象
			strategyStatisVo = JSON.parseObject(stringVo, StrategyStatisVo.class);
		}
		return strategyStatisVo;
	}

	// 设置vo到redis
	@Override
	public void setStrategyStatisVo(StrategyStatisVo strategyStatisVo) {
		String key = RedisKeys.VERIFY_STRATEGY_VO.join(strategyStatisVo.getStrategyId());
		// 由于存储到redis中需要时字符串,所以把java对象转换成json格式的字符串
		template.opsForValue().set(key, JSON.toJSONString(strategyStatisVo));
	}
}
